//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.yaukie.base.config;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.TimeoutUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.yaukie.base.redis.CacheManager;
import org.yaukie.base.util.StringTools;

@Component
public class MapTemplate<K, V> extends CacheManager<K, V> {
    private static final Logger log = LoggerFactory.getLogger(MapTemplate.class);
    private static final int DEFAULT_CACHES = 1024;
    private Map<String, CacheObject<K, V>> cachePool;

    public MapTemplate() {
        this(1024);
    }

    public MapTemplate(int cacheCount) {
        this.cachePool = new ConcurrentHashMap(cacheCount);
    }

    public <V> V get(String key) {
        CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
        if (null != cacheObject) {
            long cur = System.currentTimeMillis() / 1000L;
            if (cacheObject.getExpired() <= 0L || cacheObject.getExpired() > cur) {
                Object result = cacheObject.getValue();
                return (V) result;
            }
        }

        return null;
    }

    public V hget(String key) {
        return this.get(key);
    }

    public void set(K key, V value) {
        this.set(key, value, -1L);
    }

    public void set(K key, V value, long timeOut) {
        long expired = TimeoutUtils.toMillis(timeOut, TimeUnit.SECONDS);

        try {
            if (value instanceof String) {
                value = value;
            } else if (value instanceof Map || value instanceof List || value instanceof Set) {
                value = (V) mapper.writeValueAsString(value);
            }
        } catch (JsonProcessingException var8) {
            log.error("MAP缓存序列化出现异常{}", var8);
        }

        CacheObject cacheObject = new CacheObject(key, value, expired);
        this.cachePool.put(key.toString(), cacheObject);
    }

    public void set(K key, V value, long timeOut, TimeUnit timeUnit) {
        long expired = TimeoutUtils.toMillis(timeOut, timeUnit);
        CacheObject cacheObject = new CacheObject(key, value, expired);
        this.cachePool.put(key.toString(), cacheObject);
    }

    public boolean del(String key) {
        CacheObject v = (CacheObject) this.cachePool.remove(key);
        return StringTools.isNotNull(v);
    }

    public void clean() {
        this.cachePool.clear();
    }

    public void setCacheObject(K key, V value) {
        this.set(key, value);
    }

    public void setCacheObject(K key, V value, Integer timeout, TimeUnit timeUnit) {
        this.set(key, value, (long) timeout, timeUnit);
    }

    public boolean expire(K key, long timeout) {
        return this.expire(key, timeout, TimeUnit.SECONDS);
    }

    public boolean expire(K key, long timeout, TimeUnit unit) {
        CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
        if (StringTools.isNull(cacheObject)) {
            return false;
        } else {
            long expired = cacheObject.getExpired();
            expired = TimeoutUtils.toMillis(timeout, unit);
            cacheObject.setExpired(expired);
            this.cachePool.put(key.toString(), cacheObject);
            return true;
        }
    }

    public <V> V getCacheObject(K key) {
        V v = null;
        CacheObject cacheObject = null;
        if (this.cachePool.containsKey(key)) {
            cacheObject = (CacheObject) this.cachePool.get(key);
            v = (V) cacheObject.getValue();
        }

        return v;
    }

    public boolean deleteObject(K key) {
        return this.del(key.toString());
    }

    public long deleteObject(Collection<K> collection) {
        long count = 0L;
        if (CollectionUtils.isEmpty(collection)) {
            return count;
        } else {
            for (Iterator iterator = collection.iterator(); iterator.hasNext(); iterator.next()) {
                K k = (K) iterator.next();
                boolean delOk = this.deleteObject(k);
                if (delOk) {
                    ++count;
                }
            }

            return count;
        }
    }

    public long setCacheList(K key, List<V> dataList) {
        long count = 0L;
        if (CollectionUtils.isEmpty(dataList)) {
            return count;
        } else {
            try {
                String valueAsString = mapper.writeValueAsString(dataList);
                CacheObject cacheObject = new CacheObject(key, valueAsString, -1L);
                this.cachePool.put(key.toString(), cacheObject);
                count = (long) dataList.size();
            } catch (JsonProcessingException var7) {
                log.error("MAP缓存序列化出现异常{}", var7);
            }

            return count;
        }
    }

    public <V> List<V> getCacheList(K key) {
        if (StringTools.isNull(key)) {
            return null;
        } else if (!this.cachePool.containsKey(key.toString())) {
            return null;
        } else {
            CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
            List<V> dataList = null;

            try {
                dataList = (List) mapper.readValue(cacheObject.getValue().toString(), List.class);
            } catch (IOException var5) {
                log.error("MAP缓存序列化出现异常{}", var5);
            }

            return dataList;
        }
    }

    public <V> long setCacheSet(K key, Set<V> dataSet) {
        long count = 0L;
        if (CollectionUtils.isEmpty(dataSet)) {
            return count;
        } else {
            try {
                String valueAsString = mapper.writeValueAsString(dataSet);
                CacheObject cacheObject = new CacheObject(key, valueAsString, -1L);
                this.cachePool.put(key.toString(), cacheObject);
                count = (long) dataSet.size();
            } catch (JsonProcessingException var7) {
                log.error("MAP缓存序列化出现异常{}", var7);
            }

            return count;
        }
    }

    public <V> Set<V> getCacheSet(K key) {
        if (StringTools.isNull(key)) {
            return null;
        } else if (!this.cachePool.containsKey(key.toString())) {
            return null;
        } else {
            CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
            Set<V> set = null;

            try {
                set = (Set) mapper.readValue(cacheObject.getValue().toString(), Set.class);
            } catch (IOException var5) {
                log.error("MAP缓存序列化出现异常{}", var5);
            }

            return set;
        }
    }

    public void setCacheMap(K key, Map<K, V> dataMap) {
        try {
            String valueAsString = mapper.writeValueAsString(dataMap);
            CacheObject cacheObject = new CacheObject(key, valueAsString, -1L);
            this.cachePool.put(key.toString(), cacheObject);
        } catch (JsonProcessingException var5) {
            log.error("MAP缓存序列化出现异常{}", var5);
        }

    }

    public <V> Map<K, V> getCacheMap(K key) {
        if (StringTools.isNull(key)) {
            return null;
        } else if (!this.cachePool.containsKey(key.toString())) {
            return null;
        } else {
            CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
            Map<K, V> map = null;

            try {
                map = (Map) mapper.readValue(cacheObject.getValue().toString(), Map.class);
            } catch (IOException var5) {
                log.error("MAP缓存序列化出现异常{}", var5);
            }

            return map;
        }
    }

    public <T> void setCacheMapValue(K key, K hKey, T value) {
        Map dataMap = new HashMap();
        dataMap.put(hKey, value);

        try {
            String valueAsString = mapper.writeValueAsString(dataMap);
            CacheObject cacheObject = new CacheObject(key, valueAsString, -1L);
            this.cachePool.put(key.toString(), cacheObject);
        } catch (JsonProcessingException var7) {
            log.error("MAP缓存序列化出现异常{}", var7);
        }

    }

    public <T> T getCacheMapValue(K key, K hKey) {
        if (StringTools.isNull(key)) {
            return null;
        } else if (!this.cachePool.containsKey(key.toString())) {
            return null;
        } else {
            CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
            Map<K, V> map = null;
            V v = null;

            try {
                map = (Map) mapper.readValue(cacheObject.getValue().toString(), Map.class);
                if (map.containsKey(hKey)) {
                    v = map.get(hKey);
                }
            } catch (IOException var7) {
                log.error("MAP缓存序列化出现异常{}", var7);
            }

            return (T) v;
        }
    }

    public <V> List<V> getMultiCacheMapValue(K key, Collection<Object> hKeys) {
        if (StringTools.isNull(key)) {
            return null;
        } else if (!this.cachePool.containsKey(key.toString())) {
            return null;
        } else {
            CacheObject cacheObject = (CacheObject) this.cachePool.get(key);
            if (CollectionUtils.isEmpty(hKeys)) {
                return null;
            } else {
                List<V> dataList = new ArrayList();

                try {
                    Map<K, V> map = (Map) mapper.readValue(cacheObject.getValue().toString(), Map.class);

                    for (Iterator iterator = hKeys.iterator(); iterator.hasNext(); iterator.next()) {
                        K k = (K) iterator.next();
                        if (map.containsKey(k)) {
                            dataList.add(map.get(k));
                        }
                    }
                } catch (IOException var8) {
                    log.error("MAP缓存序列化出现异常{}", var8);
                }

                return dataList;
            }
        }
    }

    public Set<Map<K, V>> keys(K patterns) {
        long start = System.currentTimeMillis();
        Set<Map<K, V>> set = new HashSet();
        Map dataMap = new HashMap();
        if (this.cachePool.size() > 0) {
            dataMap = this.cachePool.entrySet().stream().filter((e) -> this.filterMap(e.getKey(), patterns.toString())).collect(Collectors.toMap((e) -> e.getKey(), (e) -> (CacheObject) e.getValue()));
        }
        set.add(dataMap);
        long end = System.currentTimeMillis();
        log.info("遍历所有key共耗时{}毫秒", end - start);
        return set;
    }

    private boolean filterMap(String key, String patterns) {
        if (!StringTools.isBlank(patterns) && !StringTools.equals("*", patterns)) {
            return StringTools.containsIgnoreCase(key, patterns);
        } else {
            return true;
        }
    }

    public static void main(String[] args) {
        MapTemplate mapCache = new MapTemplate();
        Map map = new HashMap();
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 3);
        mapCache.setCacheMap("a", map);
        System.out.println(JSON.toJSONString(mapCache.getCacheMap("a")));
    }

    static class CacheObject<K, V> {
        private K key;
        private V value;
        private long expired;

        public CacheObject(K key, V value, long expired) {
            this.key = key;
            this.value = value;
            this.expired = expired;
        }

        public K getKey() {
            return this.key;
        }

        public V getValue() {
            return this.value;
        }

        public long getExpired() {
            return this.expired;
        }

        public void setKey(K key) {
            this.key = key;
        }

        public void setValue(V value) {
            this.value = value;
        }

        public void setExpired(long expired) {
            this.expired = expired;
        }
    }
}
